/*
 * @Descripttion: 
 * @version: 
 * @Author: Lee
 * @Date: 2020-06-10 14:50:36
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2020-06-11 10:32:13
 */

import { isObject} from "../utils/utils"
import { arrayMethods } from "../utils/arrayMethods";
class Observe {
    constructor(data) {
        Object.defineProperty(data,'_ob_',{
            configurable: false,
            enumerable: false,
            value: this
        })
        // data._ob_ = this;
        if (Array.isArray(data)) {
            // 重写数组方法 函数劫持
            // 改变数组本身的方法对其监控
            data._proto_ = arrayMethods;// 通过原型链向上查找的方式
            // [{a: 1}]  => arr[0].a = 100;
            this.observeArray(data);

        }else {
            this.walk(data)
        }
    }
    walk(data) {
        // 遍历对象的key值
        Object.keys(data).forEach(key => {
            // 使用defindProperty设置对象的访问属性
            definedReactive(data, key, data[key])
        })
    }
    observeArray(data) {
        for(let i=0; i<data.length; i++) {
            observe(data[i])
        }
    }
}

function definedReactive(data, key, value) {
    observe(value); // 对象里嵌套多层对象
    Object.defineProperty(data, key, {
        get() {
            return value;
        },
        set(newValue) {
            if (newValue === value) return;
            observe(newValue); // 设置的对象里嵌套多层对象
            value = newValue;
        }
    })
}
export function observe(data) {
    if (!isObject(data)) {
        return;
    }
    if (data._ob_ instanceof Observe) { // _ob_唯一性
        return;
    }
    return new Observe(data) // 可以观测当前数据是否被观测过
}